package v1

import (
	"net/http"
	"strconv"

	"zhihu-api/models"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// 获取用户列表
func ListUsers(c *gin.Context) {
	var users []models.User
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	if err := models.DB.Limit(limit).Offset(offset).Find(&users).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户列表失败"})
		return
	}

	c.JSON(http.StatusOK, users)
}

// 获取用户详情
func GetUser(c *gin.Context) {
	id := c.Param("id")
	var user models.User

	if err := models.DB.First(&user, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户失败"})
		return
	}

	c.JSON(http.StatusOK, user)
}

// 更新用户信息请求
type UpdateUserRequest struct {
	Name        string `json:"name"`
	Avatar      string `json:"avatar"`
	Gender      string `json:"gender"`
	Headline    string `json:"headline"`
	Business    string `json:"business"`
	Locations   string `json:"locations"`
	Employments string `json:"employments"`
	Educations  string `json:"educations"`
}

// 更新用户信息
func UpdateUser(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查是否是当前用户
	if uint(idUint) != userID {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有权限更新其他用户的信息"})
		return
	}

	var req UpdateUserRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 查找用户
	var user models.User
	if err := models.DB.First(&user, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户失败"})
		return
	}

	// 更新用户信息
	updates := make(map[string]interface{})
	if req.Name != "" {
		updates["name"] = req.Name
	}
	if req.Avatar != "" {
		updates["avatar"] = req.Avatar
	}
	if req.Gender != "" {
		updates["gender"] = req.Gender
	}
	if req.Headline != "" {
		updates["headline"] = req.Headline
	}
	if req.Business != "" {
		updates["business"] = req.Business
	}
	if req.Locations != "" {
		updates["locations"] = req.Locations
	}
	if req.Employments != "" {
		updates["employments"] = req.Employments
	}
	if req.Educations != "" {
		updates["educations"] = req.Educations
	}

	if err := models.DB.Model(&user).Updates(updates).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新用户失败"})
		return
	}

	// 返回更新后的用户
	if err := models.DB.First(&user, id).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取更新后的用户失败"})
		return
	}

	c.JSON(http.StatusOK, user)
}

// 关注用户
func FollowUser(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查是否是自己
	if uint(idUint) == userID {
		c.JSON(http.StatusBadRequest, gin.H{"error": "不能关注自己"})
		return
	}

	// 检查目标用户是否存在
	var targetUser models.User
	if err := models.DB.First(&targetUser, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "用户不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取用户失败"})
		return
	}

	// 检查是否已关注
	var count int64
	models.DB.Model(&models.UserFollowing{}).Where("follower_id = ? AND following_id = ?", userID, idUint).Count(&count)
	if count > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "已经关注该用户"})
		return
	}

	// 创建关注关系
	following := models.UserFollowing{
		FollowerID:  userID,
		FollowingID: uint(idUint),
	}

	tx := models.DB.Begin()
	if err := tx.Create(&following).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "关注用户失败"})
		return
	}

	// 更新关注数和粉丝数
	if err := tx.Model(&models.User{}).Where("id = ?", userID).Update("following_count", gorm.Expr("following_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新关注数失败"})
		return
	}

	if err := tx.Model(&models.User{}).Where("id = ?", idUint).Update("follower_count", gorm.Expr("follower_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新粉丝数失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "关注成功"})
}

// 取消关注用户
func UnfollowUser(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查是否已关注
	var count int64
	models.DB.Model(&models.UserFollowing{}).Where("follower_id = ? AND following_id = ?", userID, idUint).Count(&count)
	if count == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未关注该用户"})
		return
	}

	tx := models.DB.Begin()
	// 删除关注关系
	if err := tx.Where("follower_id = ? AND following_id = ?", userID, idUint).Delete(&models.UserFollowing{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "取消关注失败"})
		return
	}

	// 更新关注数和粉丝数
	if err := tx.Model(&models.User{}).Where("id = ?", userID).Update("following_count", gorm.Expr("following_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新关注数失败"})
		return
	}

	if err := tx.Model(&models.User{}).Where("id = ?", idUint).Update("follower_count", gorm.Expr("follower_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新粉丝数失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "取消关注成功"})
}

// 获取用户关注的人列表
func GetUserFollowing(c *gin.Context) {
	id := c.Param("id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	var followings []models.User
	if err := models.DB.Joins("JOIN user_followings ON users.id = user_followings.following_id").
		Where("user_followings.follower_id = ?", id).
		Limit(limit).Offset(offset).Find(&followings).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取关注列表失败"})
		return
	}

	c.JSON(http.StatusOK, followings)
}

// 获取用户的粉丝列表
func GetUserFollowers(c *gin.Context) {
	id := c.Param("id")
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	var followers []models.User
	if err := models.DB.Joins("JOIN user_followings ON users.id = user_followings.follower_id").
		Where("user_followings.following_id = ?", id).
		Limit(limit).Offset(offset).Find(&followers).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取粉丝列表失败"})
		return
	}

	c.JSON(http.StatusOK, followers)
}
